/*
 * Copyright (C) 2009 Georgios J. Georgopoulos, All rights reserved.
 * 
 * This is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 3 of the License, or (at your option) any
 * later version.
 * 
 * This software is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this software; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
 * site: http://www.fsf.org.
 */
package org.gwt.mosaic.xul.client;

import org.gwt.mosaic.application.client.Application;
import org.gwt.mosaic.application.client.ApplicationConstants;
import org.gwt.mosaic.application.client.ApplicationImageBundle;
import org.gwt.mosaic.application.client.CmdAction;
import org.gwt.mosaic.application.client.ResourceConstants;
import org.gwt.mosaic.core.client.util.DelayedRunnable;
import org.gwt.mosaic.ui.client.InfoPanel;
import org.gwt.mosaic.ui.client.LoadingPanel;
import org.gwt.mosaic.ui.client.MessageBox;
import org.gwt.mosaic.ui.client.Viewport;
import org.gwt.mosaic.xul.client.application.ApplicationContext;
import org.gwt.mosaic.xul.client.application.ElementMap;
import org.gwt.mosaic.xul.client.ui.Button;
import org.gwt.mosaic.xul.client.ui.Container;
import org.gwt.mosaic.xul.client.ui.Element;
import org.gwt.mosaic.xul.client.ui.Textbox;
import org.gwt.mosaic.xul.client.ui.Vbox;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 * 
 * @author georgopoulos.georgios(at)gmail.com
 * 
 */
public class XUL extends Application implements EntryPoint {

  /**
   * Create a remote service proxy to talk to the server-side XULParserService.
   */
  private final XULParserServiceAsync xulParserService = GWT.create(XULParserService.class);

  /**
   * This is the entry point method.
   */
  public void onModuleLoad() {
    Application.launch(this,
        (ApplicationConstants) GWT.create(XULConstants.class),
        (ApplicationImageBundle) GWT.create(XULImageBundle.class));
  }

  @Override
  protected void initialize() {
    // Nothing to do here!
  }

  @CmdAction
  public void addElementCmd() {
    ApplicationContext context = (ApplicationContext) getContext();
    Vbox vbox = (Vbox) context.getElementMap().get("vbox");

    Button btn = new Button();
    btn.setLabel("Button " + System.currentTimeMillis());
    vbox.add(btn);
  }

  @CmdAction
  public void removeElementCmd() {
    ApplicationContext context = (ApplicationContext) getContext();
    Vbox vbox = (Vbox) context.getElementMap().get("vbox");

    int index = vbox.getElementCount() - 1;
    if (index > 1) {
      vbox.remove(index);
    }
  }

  // -----------------------------------------------------------------------
  // widgets.xml related commands
  // -----------------------------------------------------------------------

  @CmdAction(description = "showWidgetsCmdDescription", image = "layout")
  public void showWidgetsCmd() {
    loadDemo("widgets.xml");
  }

  @CmdAction
  public void menuItemCmd() {
    InfoPanel.show(Window.getTitle(), "MenuItem command");
  }

  @CmdAction
  public void menuItemACmd() {
    InfoPanel.show(Window.getTitle(), "MenuItem A");
  }

  @CmdAction
  public void menuItemBCmd() {
    InfoPanel.show(Window.getTitle(), "MenuItem B");
  }

  @CmdAction
  public void menuItemCCmd() {
    InfoPanel.show(Window.getTitle(), "MenuItem C");
  }
  
  @CmdAction
  public void menuItemDCmd() {
    InfoPanel.show(Window.getTitle(), "MenuItem D");
  }

  @CmdAction
  public void menuItemECmd() {
    InfoPanel.show(Window.getTitle(), "MenuItem E");
  }

  @CmdAction
  public void menuItemFCmd() {
    InfoPanel.show(Window.getTitle(), "MenuItem F");
  }

  @CmdAction
  public void menuItemGCmd() {
    InfoPanel.show(Window.getTitle(), "MenuItem G");
  }
  
  // -----------------------------------------------------------------------

  @CmdAction(description = "showCalculatorCmdDescription", image = "calculator")
  public void showCalculatorCmd() {
    loadDemo("calculator.xml");
  }

  @CmdAction(description = "calculatorAddCmdDescription")
  public void calculatorAddCmd() {
    ApplicationContext context = (ApplicationContext) getContext();
    Textbox tb1 = (Textbox) context.getElementMap().get("calculatorValue1");
    Textbox tb2 = (Textbox) context.getElementMap().get("calculatorValue2");
    Textbox tb3 = (Textbox) context.getElementMap().get("calculatorResult");
    try {
      double v1 = Double.parseDouble(tb1.getValue());
      double v2 = Double.parseDouble(tb2.getValue());
      tb3.setValue(Double.toString(v1 + v2));
    } catch (Exception e) {
      MessageBox.alert(Window.getTitle(), e.toString());
    }
  }

  @CmdAction(description = "showBoxCmdDescription", image = "layout")
  public void showBoxCmd() {
    loadDemo("box.xml");
  }

  @CmdAction(description = "showGridCmdDescription", image = "layout")
  public void showGridCmd() {
    loadDemo("grid.xml");
  }

  @CmdAction(description = "showSplitterCmdDescription", image = "splitter")
  public void showSplitterCmd() {
    loadDemo("splitter.xml");
  }

  @CmdAction(description = "showTabboxCmdDescription", image = "tabbox")
  public void showTabboxCmd() {
    loadDemo("tabbox.xml");
  }

  @CmdAction(description = "showTextboxCmdDescription", image = "layout")
  public void showTextboxCmd() {
    loadDemo("textbox.xml");
  }

  @CmdAction(description = "showButtonsCmdDescription", image = "layout")
  public void showButtonsCmd() {
    loadDemo("buttons.xml");
  }

  @CmdAction(description = "showListboxCmdDescription", image = "layout")
  public void showListboxCmd() {
    loadDemo("listbox.xml");
  }
  
  @CmdAction(image = "layout")
  public void showClientsideParserCmd () {
	    final ElementMap elementMap = getElementMap();
	    final Container contentWrapper = (Container) elementMap.get("contentWrapper");

	    ResourceConstants widgets = GWT.create(ResourceConstants.class);
	    contentWrapper.removeAll();
	    contentWrapper.add (widgets.getCalculatorSync());
  }

  private void loadDemo(final String xulFile) {
    final ElementMap elementMap = getElementMap();
    final Container contentWrapper = (Container) elementMap.get("contentWrapper");

    final Element throbber = elementMap.get("throbber");
    throbber.getUI().addStyleName("Throbber-loading");

    xulParserService.parse(xulFile, new AsyncCallback<Element>() {
      public void onFailure(Throwable caught) {
        Window.alert(caught.getLocalizedMessage());
        throbber.getUI().removeStyleName("Throbber-loading");
      }

      public void onSuccess(Element result) {
        if (result != null) {
          contentWrapper.removeAll();
          contentWrapper.add(result);
        }
        throbber.getUI().removeStyleName("Throbber-loading");
      }
    });
  }

  @Override
  protected void startup() {
    final Viewport viewport = new Viewport();

    final LoadingPanel loadingPanel = LoadingPanel.show("Loading...");

    new DelayedRunnable() {
      @Override
      public void run() {
        xulParserService.parse("showcase.xml", new AsyncCallback<Element>() {
          public void onFailure(Throwable caught) {
            Window.alert(caught.getLocalizedMessage());
          }

          public void onSuccess(Element result) {
            if (result != null) {
              viewport.getLayoutPanel().add(result.getUI());
              viewport.getLayoutPanel().setPadding(5);
              viewport.attach();
            }
            loadingPanel.hide();
          }
        });
      }
    };

  }

  private ElementMap getElementMap() {
    ApplicationContext context = (ApplicationContext) Application.getInstance().getContext();
    return context.getElementMap();
  }

}
